﻿using UnityEngine;
using System.Collections.Generic;
using Network;

public class VisualEntityManager : Singleton<VisualEntityManager>
{
    Dictionary<uint, VisualEntity> allEntities;

    public void Reset()
    {
        allEntities = new Dictionary<uint, VisualEntity>();
        RegisterNetworkMessage();
    }

    public void Destroy()
    {
        allEntities = null;
        UnregisterNetworkMessage();
    }

    public VisualEntity GetEntity(uint EntityID)
    {
        if (allEntities == null)
            return null;
        if (allEntities.ContainsKey(EntityID))
            return allEntities[EntityID];
        else
            return null;
    }

    void _CreateEntity(MsgObject msg)
    {
        gamemanager_create_entity proto = ProtoUtil.DeserializeProto<gamemanager_create_entity>(msg.msgBody);
        string prefabPath = proto.prefab_path; uint entityID = proto.entity_id;
        VisualEntity vEntity = VisualEntity.InitVisualEntitiy(prefabPath, entityID);
        allEntities.Add(vEntity.entityID, vEntity);

        if(proto.player_id == Mainloop.Instance.MyPlayerID)
        {
            CameraController cameraController = Camera.main.GetComponent<CameraController>();
            cameraController.SetFocusing(vEntity.transform);
        }
    }

    void _DelEntity(MsgObject msg)
    {
        gamemanager_del_entity proto = ProtoUtil.DeserializeProto<gamemanager_del_entity>(msg.msgBody);
        uint EntityID = proto.entity_id;
        VisualEntity vEntity = GetEntity(EntityID);
        if (vEntity != null)
        {
            vEntity.Destroy();
            allEntities.Remove(EntityID);
            GameObject.DestroyImmediate(vEntity.gameObject);
        }
    }

    void RegisterNetworkMessage()
    {
        NetManager.Instance.RegistUdpMsg(OpCode.gamemanager_create_entity, _CreateEntity);
        NetManager.Instance.RegistUdpMsg(OpCode.gamemanager_del_entity, _DelEntity);
        NetManager.Instance.RegistUdpMsg(OpCode.restore_state, _RestoreState);
    }

    void UnregisterNetworkMessage()
    {
        NetManager.Instance.UnregistUdpMsg(OpCode.gamemanager_create_entity);
        NetManager.Instance.UnregistUdpMsg(OpCode.gamemanager_del_entity);
        NetManager.Instance.UnregistUdpMsg(OpCode.restore_state);
    }

    #region SyncState
    public void SyncState(int toPlayerID)
    {
        foreach(VisualEntity vEntity in allEntities.Values)
        {
            sync_state proto = new sync_state();
            proto.to_player_id = toPlayerID;
            sync_state_content message = new sync_state_content();
            message.entity_id = vEntity.entityID;
            message.prefab_path = vEntity.PrefabPath;
            vEntity.GetSyncMessage(message);
            proto.content = ProtoUtil.SerializeProto(message);
            NetManager.Instance.SendUdpMessage(OpCode.sync_state, ProtoUtil.SerializeProto(proto));
        }
    }

    void _RestoreState(MsgObject msg)
    {
        
        restore_state message = ProtoUtil.DeserializeProto<restore_state>(msg.msgBody);
        sync_state_content content = ProtoUtil.DeserializeProto<sync_state_content>(message.content);
        uint entityID = content.entity_id;
        string prefabPath = content.prefab_path;
        VisualEntity vEntity = VisualEntity.InitVisualEntitiy(prefabPath, entityID);
        allEntities.Add(vEntity.entityID, vEntity);

        vEntity.RestoreState(content);
    }
    #endregion
}
